﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Application
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Linq;
    using System.Windows.Forms;

    using Mews.Application.Controls;
    using Mews.Application.Properties;
    using Mews.Mime;
    using Mews.Net.Nntp.Cache;

    [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Another part already documents the class.")]
    internal partial class MainForm
    {
        /// <summary>Implements the controller for outbound articles.</summary>
        private abstract class MyArticlesControllerBase : Controller, IController
        {
            private readonly MenuItem contextToggleIsDeletedMenuItem;

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            /// <summary>See <see cref="IController.Document"/>.</summary>
            public abstract object Document { get; }

            /// <summary>See <see cref="IController.UpdateCount"/>.</summary>
            public abstract void UpdateCount();

            /// <summary>See <see cref="IController.Update"/>.</summary>
            public void Update()
            {
                this.ClearTreeViewNodes();
                AddArticles(this.GetArticles(), this.MainForm.treeView.Nodes);
                this.UpdateStatus();
                this.MainForm.quickMenuItem.Enabled = this.MainForm.treeView.SelectedNode != null;
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            internal sealed override void OnQuickMenuItem_Click(object sender, EventArgs e)
            {
                this.OnToggleIsDeletedMenuItem_Click(sender, e);
            }

            internal sealed override void OnTreeView_AfterSelect(object sender, TreeViewEventArgs e)
            {
                var article = GetArticle(e.Node);
                this.MainForm.quickMenuItem.Enabled = true;
            }

            internal sealed override void OnContextMenu_Popup(object sender, EventArgs e)
            {
                this.contextToggleIsDeletedMenuItem.Enabled = this.MainForm.treeView.SelectedNode != null;
            }

            internal void RemoveCurrentArticle()
            {
                this.MainForm.quickMenuItem.Enabled = false;
                this.MainForm.treeView.SelectedNode.Remove();
                this.UpdateStatus();
                this.UpdateCount();
            }

            internal static IOutboundArticle GetArticle(TreeNode node)
            {
                return (IOutboundArticle)(node == null ? null : node.Tag);
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            /// <summary>Initializes a new instance of the <see cref="MyArticlesControllerBase"/> class.</summary>
            protected MyArticlesControllerBase(MainForm mainForm, string toggleIsDeletedText) : base(mainForm)
            {
                this.MainForm.treeView.ShowLines = false;

                this.MainForm.quickMenuItem.Text = toggleIsDeletedText;

                this.MainForm.sendReceiveMinimalGroupMenuItem.Enabled = false;
                this.MainForm.sendReceiveMinimalHostMenuItem.Enabled = false;
                this.MainForm.sendReceiveFullGroupMenuItem.Enabled = false;
                this.MainForm.sendReceiveFullHostMenuItem.Enabled = false;
                this.MainForm.filterMenuItem.Enabled = false;
                this.MainForm.markGroupAsReadMenuItem.Enabled = false;
                this.MainForm.newMenuItem.Enabled = false;

                this.contextToggleIsDeletedMenuItem = new MenuItem() { Text = toggleIsDeletedText };
                this.contextToggleIsDeletedMenuItem.Click += this.OnToggleIsDeletedMenuItem_Click;
                this.MainForm.contextMenu.MenuItems.Add(this.contextToggleIsDeletedMenuItem);
            }

            /// <summary>Gets the name of the (virtual) folder the articles reside in.</summary>
            protected abstract string FolderName { get; }

            /// <summary>Gets the articles to be shown on the <see cref="MainForm"/>.</summary>
            protected abstract IEnumerable<IOutboundArticle> GetArticles();

            /// <summary>See <see cref="IDisposable.Dispose"/>.</summary>
            protected sealed override void Dispose(bool disposing)
            {
                try
                {
                    this.contextToggleIsDeletedMenuItem.Click -= this.OnToggleIsDeletedMenuItem_Click;
                    this.contextToggleIsDeletedMenuItem.Dispose();
                }
                finally
                {
                    base.Dispose(disposing);
                }
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            ////////// this.ContextMenu handlers //////////

            private void OnToggleIsDeletedMenuItem_Click(object sender, EventArgs e)
            {
                var article = GetArticle(this.MainForm.treeView.SelectedNode);

                if (article != null)
                {
                    article.IsDeleted = !article.IsDeleted;
                    this.RemoveCurrentArticle();
                }
            }

            ////////// Helper methods //////////

            private void UpdateStatus()
            {
                this.MainForm.statusTextBox.Text = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.MyArticlesStatus,
                    this.FolderName,
                    this.MainForm.treeView.Nodes.Count);
            }

            private static void AddArticles(IEnumerable<IOutboundArticle> articles, TreeNodeCollection treeNodes)
            {
                foreach (var article in articles)
                {
                    TreeNode node = new TreeNode(article.Subject);
                    node.Tag = article;
                    treeNodes.Add(node);
                    node.SetAppearance(false, 4, 4);
                }
            }
        }
    }
}
